package com.je.core.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.je.core.base.MethodArgument;
import com.je.core.constants.ConstantVars;
import com.je.core.constants.tree.NodeType;
import com.je.core.constants.wf.AudFlagStatus;
import com.je.core.dao.PCDaoTemplateImpl;
import com.je.core.entity.extjs.JSONTreeNode;
import com.je.core.exception.PlatformException;
import com.je.core.exception.PlatformExceptionEnum;
import com.je.core.mapper.query.ConditionEnum;
import com.je.core.mapper.query.Query;
import com.je.core.util.*;
import com.je.core.util.bean.BeanUtils;
import com.je.core.util.bean.DynaBean;
import com.je.develop.service.CodeGenManager;
import com.je.develop.service.FunInfoManager;
import com.je.develop.service.FuncPermManager;
import com.je.develop.vo.FuncInfo;
import com.je.develop.vo.FuncPermVo;
import com.je.develop.vo.FuncRelation;
import com.je.develop.vo.FuncRelationField;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.micromail.service.MicromailManager;
import com.je.paas.document.model.MetadataEnum;
import com.je.paas.document.model.UploadTypeEnum;
import com.je.paas.document.model.dto.FileCopyDTO;
import com.je.paas.document.service.DocumentBusService;
import com.je.rbac.model.Department;
import com.je.rbac.model.EndUser;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.sql.Clob;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 通用业务方法实现
 *
 * @author wangmm@ketr.com.cn
 * @date 2019/12/6
 */
@Service
public class CommonServiceImpl implements CommonService {
    /**
     * 基础数据操作封装
     */
    @Autowired
    private MetaService metaService;
    /**
     * 文件操作service
     */
    @Autowired
    private DocumentBusService documentBusService;
    @Autowired
    private MicromailManager micromailManager;
    @Autowired
    private FunInfoManager funInfoManager;
    @Autowired
    private FuncPermManager funcPermManager;
    @Autowired
    private CodeGenManager codeGenManager;
    @Resource(name = "taskExecutor")
    private TaskExecutor taskExecutor;
    @Autowired
    protected PlatformManager manager;

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Override
    public void buildMarkInfo(List<Map<String, Object>> datas, String tableCode, EndUser currentUser, String funcId) {

        if (datas.isEmpty()) {
            return;
        }
        String pkCode = BeanUtils.getInstance().getPKeyFieldNames(tableCode);

        ConditionsWrapper wrapper = ConditionsWrapper.builder().eq("MARK_USERID", currentUser.getUserId()).eq("MARK_FUNCID", funcId);

        //分割list避免in语句超长
        int step = 900;
        List<List<Map<String, Object>>> lists = Lists.partition(datas, step);

        //拼接in语句
        wrapper.and(i -> {
            for (List<Map<String, Object>> list : lists) {
                //主键集合
                List<Object> pkVals = new ArrayList<>();
                for (Map<String, Object> bean : list) {
                    Object pkValue = bean.get(pkCode);
                    if (pkValue != null && StringUtils.isNotBlank(pkValue.toString())) {
                        pkVals.add(pkValue);
                    }
                }
                //!i.isEmpty()  第一次调用时 i 为空 所以不拼 or
                i.or(!i.isEmpty()).in("MARK_MODELID", pkVals);
            }
        });

        //查询结果
        List<DynaBean> marks = metaService.select("JE_CORE_MARK", wrapper);

        //list转map  key为业务bean主键MARK_MODELID  value为标记数据如: 1,2,5   2,3,4
        Map<String, String> markInfos = marks.stream()
                //去重 MARK_MODELID
                .collect(Collectors.collectingAndThen(
                        Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(p -> p.getStr("MARK_MODELID")))), ArrayList::new)).stream()
                .collect(Collectors.toMap(p -> p.getStr("MARK_MODELID"), p -> {
                    List<String> vals = new ArrayList<>();
                    for (int i = 1; i <= 7; i++) {
                        if ("1".equals(p.getStr("MARK_" + i, "0"))) {
                            vals.add(i + "");
                        }
                    }
                    return StringUtil.buildSplitString(ArrayUtils.getArray(vals), ",");
                }));

        //查找业务数据对应的标签数据
        for (Map<String, Object> obj : datas) {
            Object pkValue = obj.get(pkCode);
            obj.put("SY__MARK", markInfos.getOrDefault(pkValue, ""));
        }
    }

    @Override
    public void buildPostilInfo(List<Map<String, Object>> lists, String tableCode, String funcId) {

        //主键字段编码
        String pkCode = BeanUtils.getInstance().getPKeyFieldNames(tableCode);

        //主键集合
        List<String> pkCodes = lists.stream().filter(p -> p.containsKey(pkCode)).map(p -> p.get(pkCode).toString()).collect(Collectors.toList());

        List<Map<String, Object>> counts = metaService.selectSql(
                "SELECT POSTIL_MODELID,COUNT(*) AS POSTIL_NUM FROM JE_CORE_POSTIL WHERE POSTIL_FUNCID={0} AND POSTIL_MODELID IN ({1}) GROUP BY POSTIL_MODELID"
                , funcId, pkCodes);
        Map<String, Integer> valsInfo = new HashMap<>();
        //获取微邮数量
        Map<String, Integer> micCounts = micromailManager.getMicromailCount(StringUtil.buildArrayToString(pkCodes));
        for (Map countInfo : counts) {
            String modelId = countInfo.get("POSTIL_MODELID") + "";
            Integer num = Integer.parseInt(StringUtil.getDefaultValue(countInfo.get("POSTIL_NUM"), "0"));
            if (!Objects.isNull(micCounts.get(modelId))) {
                num += micCounts.get(modelId);
            }
            micCounts.remove(modelId);
            valsInfo.put(modelId, num);
        }
        for (Map.Entry<String, Integer> entry : micCounts.entrySet()) {
            valsInfo.put(entry.getKey(), entry.getValue());
        }
        for (Map<String, Object> obj : lists) {
            if (!obj.containsKey(pkCode)) {
                continue;
            }
            String pkValue = obj.get(pkCode).toString();
            if (valsInfo.containsKey(pkValue)) {
                obj.put("SY__POSTIL", valsInfo.get(pkValue));
            } else {
                obj.put("SY__POSTIL", 0);
            }
        }
    }

    @Override
    public void buildFuncEditInfo(List<Map<String, Object>> lists, String tableCode, EndUser currentUser, String funcCode) {
        //主键字段编码
        String pkCode = BeanUtils.getInstance().getPKeyFieldNames(tableCode);

        //主键集合
        List<String> pkCodes = lists.stream().filter(p -> p.containsKey(pkCode)).map(p -> p.get(pkCode).toString()).collect(Collectors.toList());

        List<Map<String, Object>> funcEdits = metaService.selectSql(
                "SELECT FUNCEDIT_PKVALUE,FUNCEDIT_USERID,FUNCEDIT_NEW FROM JE_CORE_FUNCEDIT WHERE FUNCEDIT_USERID={0} AND FUNCEDIT_FUNCCODE='" + funcCode + "' AND FUNCEDIT_PKVALUE IN ({1}) "
                , currentUser.getUserId(), pkCodes);
        Map<String, String> dataVals = new HashMap<>();
        for (Map funcEdit : funcEdits) {
            String modelId = funcEdit.get("FUNCEDIT_PKVALUE") + "";
            dataVals.put(modelId, funcEdit.get("FUNCEDIT_NEW") + "");
        }
        for (Map<String, Object> obj : lists) {
            if (!obj.containsKey(pkCode)) {
                continue;
            }
            String pkValue = obj.get(pkCode).toString();
            if (dataVals.containsKey(pkValue)) {
                obj.put("SY_FUNCEDIT", dataVals.get(pkValue) + "");
            } else {
                obj.put("SY_FUNCEDIT", "2");
            }
        }
    }

    @Override
    public void buildModelCreateInfo(DynaBean model, EndUser currentUser) {
        //校验
        if (null != currentUser && null != currentUser.getDept()) {
            //用户部门
            Department currentDept = currentUser.getDept();
            //如果前台传入登录人信息则不构建，以后去掉
            if (StringUtil.isEmpty(model.getStr("SY_CREATEUSER")) || model.getStr("SY_CREATEUSER").equals("@USER_CODE@")) {
                model.put("SY_CREATEUSER", currentUser.getUserCode());
                model.put("SY_CREATEUSERID", currentUser.getId());
                model.put("SY_CREATEUSERNAME", currentUser.getUsername());
            }
            if (StringUtil.isEmpty(model.get("SY_CREATEORG"))) {
                model.put("SY_CREATEORGID", currentDept.getDeptId());
                model.put("SY_CREATEORG", currentDept.getDeptCode());
                model.put("SY_CREATEORGNAME", currentDept.getDeptName());
            }
            if (StringUtil.isEmpty(model.get("SY_JTGSID"))) {
                model.put("SY_JTGSMC", currentUser.getJtgsMc());
                model.put("SY_JTGSID", currentUser.getJtgsId());
            }
            model.put("SY_ZHMC", currentUser.getZhMc());
            model.put("SY_ZHID", currentUser.getZhId());
            model.put("SY_CREATETIME", DateUtils.formatDateTime(new Date()));
        }
        model.put("SY_AUDFLAG", AudFlagStatus.NOSTATUS);
        model.put("SY_PDID", "");
        model.put("SY_PIID", "");
    }

    @Override
    public void buildModelModifyInfo(DynaBean model, EndUser currentUser) {
        //校验
        if (null != currentUser && null != currentUser.getDept()) {
            //用户部门
            Department currentDept = currentUser.getDept();
            model.put("SY_MODIFYUSERID", currentUser.getUserId());
            model.put("SY_MODIFYUSER", currentUser.getUserCode());
            model.put("SY_MODIFYUSERNAME", currentUser.getUsername());
            model.put("SY_MODIFYORGID", currentDept.getDeptId());
            model.put("SY_MODIFYORG", currentDept.getDeptCode());
            model.put("SY_MODIFYORGNAME", currentDept.getDeptName());
            model.put("SY_MODIFYTIME", DateUtils.formatDateTime(new Date()));
        }
    }

    @Override
    public String buildCode(String fieldCode, String funcCode, DynaBean dynaBean, String zhId) {
        DynaBean funcInfo = metaService.selectOne("JE_CORE_FUNCINFO", ConditionsWrapper.builder().eq("FUNCINFO_FUNCCODE", funcCode).in("FUNCINFO_NODEINFOTYPE", "FUNC", "FUNCFIELD"), "FUNCINFO_FUNCNAME,FUNCINFO_FUNCCODE,JE_CORE_FUNCINFO_ID,FUNCINFO_TABLENAME");
        if (funcInfo == null) {
            return "";
        }
        DynaBean field = metaService.selectOne("JE_CORE_RESOURCEFIELD", ConditionsWrapper.builder().eq("RESOURCEFIELD_FUNCINFO_ID", funcInfo.getStr("JE_CORE_FUNCINFO_ID")).eq("RESOURCEFIELD_CODE", fieldCode));
        if (field == null) {
            return "";
        }
        String configInfoStr = field.getStr("RESOURCEFIELD_CONFIGINFO");
        if (StringUtil.isEmpty(configInfoStr)) {
            return "";
        }
        JSONObject infos = new JSONObject();
        String tableCode = funcInfo.getStr("FUNCINFO_TABLENAME", "");
        DynaBean table = BeanUtils.getInstance().getResourceTable(tableCode);
        infos.put("TABLECODE", tableCode);
        if (table != null) {
            infos.put("TABLENAME", table.getStr("RESOURCETABLE_TABLENAME"));
        }
        infos.put("FUNCID", funcInfo.getStr("JE_CORE_FUNCINFO_ID"));
        infos.put("FUNCCODE", funcCode);
        infos.put("FUNCNAME", funcInfo.getStr("FUNCINFO_FUNCNAME"));
        if (StringUtil.isNotEmpty(zhId)) {
            infos.put("ZHID", zhId);
        }
        return codeGenerator(JSON.parseArray(configInfoStr), dynaBean, fieldCode, infos);
    }

    @Override
    public void buildCode(String codeGenFieldInfo, DynaBean dynaBean, String zhId) {
        JSONArray array = JSON.parseArray(codeGenFieldInfo);
        for (int i = 0; i < array.size(); i++) {
            JSONObject o = array.getJSONObject(i);
            String fieldName = o.getString("code");
            String funcId = o.getString("funcId");
            String funcCode = "";
            if (o.containsKey("funcCode")) {
                funcCode = o.getString("funcCode");
            }
            String tableCode = "";
            if (o.containsKey("tableCode")) {
                tableCode = o.getString("tableCode");
            }
            String tableName = "";
            if (StringUtil.isNotEmpty(tableCode)) {
                DynaBean table = BeanUtils.getInstance().getResourceTable(tableCode);
                tableName = table.getStr("RESOURCETABLE_TABLENAME");
            }
            String funcName = o.getString("funcName");
            JSONObject infos = new JSONObject();
            infos.put("FUNCID", funcId);
            infos.put("FUNCCODE", funcCode);
            infos.put("FUNCNAME", funcName);
            infos.put("TABLENAME", tableName);
            infos.put("TABLECODE", tableCode);
            if (StringUtil.isNotEmpty(zhId)) {
                infos.put("ZHID", zhId);
            }
            JSONArray codePatterns = o.getJSONArray("configInfo");
            if (StringUtil.isNotEmpty(fieldName) && StringUtil.isNotEmpty(funcId) && codePatterns.size() > 0) {
                String fieldCodeValue = codeGenerator(codePatterns, dynaBean, fieldName, infos);
                dynaBean.setStr(fieldName, fieldCodeValue);
            }
        }
    }

    public String codeGenerator(JSONArray codePatterns, DynaBean entity, String fieldName, JSONObject infos) {
        StringBuffer codeValue = new StringBuffer();
        String zhId = "";
        if (infos.containsKey("ZHID")) {
            zhId = infos.getString("ZHID");
        }
        for (int i = 0; i < codePatterns.size(); i++) {
            JSONObject codePattern = codePatterns.getJSONObject(i);
            String qzfs = codePattern.getString("qzfs");//取值方式
            String dyz = codePattern.getString("dyz"); //对应值
            String jq = codePattern.getString("jq");//截取格式
            String gs = codePattern.getString("gs");//日期格式
            //常量
            if ("CL".equals(qzfs)) {
                if (StringUtil.isNotEmpty(dyz)) {
                    codeValue.append(dyz);
                }
                //全局变量
            } else if ("QJBL".equals(qzfs)) {
                if (StringUtil.isNotEmpty(dyz) && StringUtil.isNotEmpty(WebUtils.getBackVar(dyz))) {
                    codeValue.append(StringUtil.getSubValue(WebUtils.getBackVar(dyz), jq));
                } else if (StringUtil.isNotEmpty(dyz) && StringUtil.isNotEmpty(StringUtil.codeToValue(dyz))) {
                    if (StringUtil.isNotEmpty(gs)) {
                        Date date = DateUtils.getDate(StringUtil.codeToValue(dyz), DateUtils.DAFAULT_DATETIME_FORMAT);
                        if (date == null) {
                            date = DateUtils.getDate(StringUtil.codeToValue(dyz), DateUtils.DAFAULT_DATE_FORMAT);
                        }
                        if (date != null) {
                            codeValue.append(StringUtil.getSubValue(DateUtils.formatDate(date, gs), jq));
                        }
                    } else {
                        codeValue.append(StringUtil.getSubValue(StringUtil.codeToValue(dyz), jq));
                    }
                }
            } else if ("BDZD".equals(qzfs)) {
                if (StringUtil.isNotEmpty(dyz) && StringUtil.isNotEmpty(entity.getStr(dyz, ""))) {
                    if (StringUtil.isNotEmpty(gs)) {
                        Date date = DateUtils.getDate(entity.getStr(dyz, ""), DateUtils.DAFAULT_DATETIME_FORMAT);
                        if (date == null) {
                            date = DateUtils.getDate(entity.getStr(dyz, ""), DateUtils.DAFAULT_DATE_FORMAT);
                        }
                        if (date != null) {
                            codeValue.append(StringUtil.getSubValue(DateUtils.formatDate(date, gs), jq));
                        }
                    } else {
                        codeValue.append(StringUtil.getSubValue(entity.getStr(dyz, ""), jq));
                    }
                }
            } else if ("LSH".equals(qzfs)) {
                String cd = codePattern.getString("cd");//长度
                String lshDyz = StringUtil.getDefaultValue(codePattern.getString("dyz") + "", "FUNC");//流水号基准
                String codeBase = codePattern.getString("qsh");//起始号
                String step = codePattern.getString("bc");//步长
                String cycle = codePattern.getString("zq");//周期
                if (!"TABLE".equals(lshDyz)) {
                    lshDyz = "FUNC";
                }
                infos.put("TYPE", lshDyz);
                if (StringUtil.isNotEmpty(cd) && StringUtil.isNotEmpty(codeBase) && StringUtil.isNotEmpty(step)) { // && StringUtil.isNotEmpty(cycle)
                    //格式转换
                    net.sf.json.JSONObject json = net.sf.json.JSONObject.fromObject(infos.toJSONString());
                    if (StringUtil.isNotEmpty(zhId)) {
                        codeValue.append(codeGenManager.getSeq(json, fieldName, codeBase, step, cycle, Integer.parseInt(cd), zhId));
                    } else {
                        codeValue.append(codeGenManager.getSeq(json, fieldName, codeBase, step, cycle, Integer.parseInt(cd)));
                    }
                }
            }
        }
        return codeValue.toString();
    }

    @Override
    public DynaBean doSave(DynaBean dynaBean) {
        String tableCode = dynaBean.getTableCode();
        if (StringUtil.isEmpty(dynaBean.getStr("SY_STATUS"))) {
            dynaBean.set("SY_STATUS", "1");//默认为启用数据
        }
        metaService.insert(dynaBean);

        if (StringUtil.isNotEmpty(dynaBean.getStr("SY_PATH"))) {
            String uuid = dynaBean.getStr(dynaBean.getPkCode(), "");
            if (StringUtil.isEmpty(uuid)) {
                throw new PlatformException("主键保存后未生成", PlatformExceptionEnum.UNKOWN_ERROR);
            }
            dynaBean.setStr(dynaBean.getPkCode(), uuid);
            dynaBean.set("SY_PARENTPATH", dynaBean.getStr("SY_PATH"));
            dynaBean.set("SY_PATH", dynaBean.getStr("SY_PATH") + "/" + uuid);
            if (StringUtil.isEmpty(dynaBean.getStr("SY_NODETYPE"))) {
                dynaBean.set("SY_NODETYPE", NodeType.LEAF);
            }
            DynaBean parent = metaService.selectOneByPk(dynaBean.getTableCode(), dynaBean.getStr("SY_PARENT"), dynaBean.getPkCode() + ",SY_NODETYPE,SY_TREEORDERINDEX");
            if (parent != null && NodeType.LEAF.equals(parent.getStr("SY_NODETYPE"))) {
                metaService.executeSql(ConditionsWrapper.builder(
                        " UPDATE " + tableCode + " SET SY_NODETYPE='" + NodeType.GENERAL +
                                "' where " + dynaBean.getPkCode() + " = '" + dynaBean.getStr("SY_PARENT") +
                                "' AND SY_NODETYPE!='" + NodeType.ROOT + "'").table(tableCode));
            }
            //构建序号
            if (dynaBean.containsKey("SY_TREEORDERINDEX") && StringUtil.isNotEmpty(dynaBean.getStr("SY_PARENT"))) {
                dynaBean.set("SY_TREEORDERINDEX", parent.getStr("SY_TREEORDERINDEX"));
                generateTreeOrderIndex(dynaBean);
            }
        }
        metaService.update(dynaBean);
        return dynaBean;
    }

    @Override
    public void generateTreeOrderIndex(DynaBean dynaBean) {
        String parent = dynaBean.getStr("SY_PARENT");
        String parentNumber = dynaBean.getStr("SY_TREEORDERINDEX", "");
        List<Map<String, Object>> objs = null;
        if (PCDaoTemplateImpl.DBNAME.equals(ConstantVars.STR_DM)) {
            objs = metaService.selectSql(ConditionsWrapper.builder(
                    "select MAX(SUBSTRING(SY_TREEORDERINDEX)) AS MAX FROM " + dynaBean.getTableCode() + " WHERE SY_PARENT= {0}", parent)
                    .table(dynaBean.getTableCode()));
        } else {
            objs = metaService.selectSql(ConditionsWrapper.builder(
                    "select MAX(SY_TREEORDERINDEX) AS MAX FROM " + dynaBean.getTableCode() + " WHERE SY_PARENT= {0}", parent)
                    .table(dynaBean.getTableCode()));
        }
        if (objs != null && !objs.isEmpty() && objs.get(0) != null) {
            String maxValue = StringUtil.getDefaultValue(objs.get(0).get("MAX"), "");
            Integer value = 0;
            if (maxValue.length() > parentNumber.length()) {
                value = Integer.parseInt(StringUtil.getDefaultValue((objs.get(0).get("MAX") + "").substring(parentNumber.length()), "0")) + 1;
            } else {
                value = 1;
            }
            dynaBean.setStr("SY_TREEORDERINDEX", parentNumber += StringUtil.preFillUp(value.toString(), 6, '0'));
            dynaBean.set("SY_ORDERINDEX", value);
        } else {
            dynaBean.set("SY_ORDERINDEX", 1);
            dynaBean.setStr("SY_TREEORDERINDEX", parentNumber += StringUtil.preFillUp("1", 6, '0'));
        }
    }

    /**
     * 文件保存业务元数据信息
     *
     * @param dynaBean         业务bean
     * @param batchFilesFields 多附件字段名
     * @param uploadableFields 单附件字段名
     * @param funcCode         功能编码
     * @return void
     */
    @Override
    public void doSaveFileMetadata(DynaBean dynaBean, String batchFilesFields, String uploadableFields, String funcCode) {

        //无附件字段  跳过逻辑
        if (StringUtil.isEmpty(batchFilesFields) && StringUtil.isEmpty(uploadableFields)) {
            return;
        }

        //获取表名
        String tableCode = dynaBean.getTableCode();
        //获取主键字段名
        String pkCode = dynaBean.getPkCode();
        //设置主键，因为传过来的DynaBean可能是未设置主键的
        String pkValue = dynaBean.getPkValue();
        if (StringUtil.isEmpty(pkValue)) {
            throw new PlatformException("主键保存后未生成", PlatformExceptionEnum.UNKOWN_ERROR);
        }


        String userId = SecurityUserHolder.getCurrentUser().getUserId();

        //遍历多附件字段信息
        if (StringUtil.isNotEmpty(batchFilesFields)) {
            for (String fieldCode : batchFilesFields.split(",")) {

                if (StringUtils.isBlank(dynaBean.getStr(fieldCode))) {
                    continue;
                }
                //组装元数据信息
                JSONObject metadataObject = new JSONObject();
                metadataObject.put(MetadataEnum.tableCode.getCode(), tableCode);
                metadataObject.put(MetadataEnum.pkValue.getCode(), pkValue);
                metadataObject.put(MetadataEnum.funcCode.getCode(), funcCode);
                metadataObject.put(MetadataEnum.uploadType.getCode(), UploadTypeEnum.FORM.getCode());
                metadataObject.put(MetadataEnum.tenantId.getCode(), SecurityUserHolder.getCurrentUser().getZhId());
                //设置元数据字段名
                metadataObject.put(MetadataEnum.fieldCode.getCode(), fieldCode);

                //获取字段中附件集合
                JSONArray files = JSONArray.parseArray(StringUtil.getDefaultValue(dynaBean.getStr(fieldCode), "[]"));
                //记录有效key
                List<String> usedFileKey = new ArrayList<>();
                //遍历附件
                for (Integer i = 0; i < files.size(); i++) {
                    JSONObject fileObj = files.getJSONObject(i);
                    //获取文件key
                    String fileKey = fileObj.getString("path");
                    usedFileKey.add(fileKey);
                }

                taskExecutor.execute(() -> {
                    //保存文件元数据
                    documentBusService.saveFileMetadata(userId, metadataObject, usedFileKey);
                    //清理字段相关附件信息
                    documentBusService.updateFiledFile(userId, tableCode, pkValue, fieldCode, usedFileKey);
                });
            }
        }
        //遍历单附件字段信息
        if (StringUtil.isNotEmpty(uploadableFields)) {
            for (String fieldCode : uploadableFields.split(",")) {

                if (StringUtils.isBlank(dynaBean.getStr(fieldCode))) {
                    continue;
                }
                //组装元数据信息
                JSONObject metadataObject = new JSONObject();
                metadataObject.put(MetadataEnum.tableCode.getCode(), tableCode);
                metadataObject.put(MetadataEnum.pkValue.getCode(), pkValue);
                metadataObject.put(MetadataEnum.funcCode.getCode(), funcCode);
                metadataObject.put(MetadataEnum.uploadType.getCode(), UploadTypeEnum.FORM.getCode());
                metadataObject.put(MetadataEnum.tenantId.getCode(), SecurityUserHolder.getCurrentUser().getZhId());
                //设置元数据字段名
                metadataObject.put(MetadataEnum.fieldCode.getCode(), fieldCode);
                //记录有效key
                List<String> usedFileKey = new ArrayList<>();
                //获取文件key
                String value = StringUtil.getDefaultValue(dynaBean.getStr(fieldCode));
                if (StringUtil.isNotEmpty(value) && value.contains("*")) {
                    String[] fileMsg = value.split("\\*");
                    usedFileKey.add(fileMsg[fileMsg.length - 1]);
                }

                taskExecutor.execute(() -> {
                    //保存文件元数据
                    documentBusService.saveFileMetadata(userId, metadataObject, usedFileKey);
                    //清理字段相关附件信息
                    documentBusService.updateFiledFile(userId, tableCode, pkValue, fieldCode, usedFileKey);
                });
            }
        }

    }

    @Override
    public void doViewData(String funcCode, DynaBean dynaBean) {
        DynaBean funcInfo = metaService.selectOne("JE_CORE_FUNCINFO", ConditionsWrapper.builder().eq("FUNCINFO_FUNCCODE", funcCode), "FUNCINFO_VIEWCONFIGINFO");
        String viewConfigInfo = funcInfo.getStr("FUNCINFO_VIEWCONFIGINFO");
        doViewData(funcCode, dynaBean, viewConfigInfo);
    }

    @Override
    public void doViewData(String funcCode, DynaBean dynaBean, String viewConfigInfo) {
        if (StringUtils.isBlank(viewConfigInfo) || viewConfigInfo.equals("[]")) {
            //TODO[bug] 解决视图视图增删改查问题，没有配置则按照原逻辑进行更新，不在这里修改
//            if (StringUtils.isBlank(dynaBean.getPkValue())) {
//                doSave(dynaBean);
//            } else {
//                metaService.update(dynaBean);
//            }
            return;
        }
        JSONArray arrays = JSONArray.parseArray(viewConfigInfo);
        for (int i = 0; i < arrays.size(); i++) {
            JSONObject obj = arrays.getJSONObject(i);
            String tableCode = obj.getString("tableCode");
            String pkCode = obj.getString("pkCode");
            dynaBean.set(pkCode, dynaBean.getStr(pkCode));
            String viewPkCode = obj.getString("viewFieldCode");
            String fieldCodes = obj.getString("fieldCodes");
            String updateFlag = obj.getString("updateData");
            String insertFlag = "0";
            if (obj.containsKey("insertData")) {
//                insertFlag = "insertData";
                insertFlag = obj.getString("insertData");
            }
            String doFieldCodes = "";
            //TODO 前端应该传doFieldCodes
            if (obj.containsKey("dofieldCodes")) {
                doFieldCodes = obj.getString("dofieldCodes");
            }
            if (StringUtil.isNotEmpty(tableCode) && StringUtil.isNotEmpty(pkCode) && StringUtil.isNotEmpty(viewPkCode)
                    && StringUtil.isNotEmpty(fieldCodes) && "1".equals(updateFlag)) {
                if (!dynaBean.containsKey(viewPkCode)) {
                    continue;
                }
                String pkValue = dynaBean.getStr(viewPkCode);
                DynaBean bean = new DynaBean(tableCode, true);
                for (String fieldCode : fieldCodes.split(",")) {
                    if (dynaBean.containsKey(fieldCode)) {
                        bean.set(fieldCode, dynaBean.get(fieldCode));
                        dynaBean.set(fieldCode, dynaBean.get(fieldCode));
                    }
                }
                if (StringUtil.isNotEmpty(doFieldCodes) && doFieldCodes.split(",").length > 1) {
                    String[] thisFields = doFieldCodes.split(",")[0].split("~");
                    String[] targerFields = doFieldCodes.split(",")[1].split("~");
                    for (int j = 0; j < thisFields.length; j++) {
                        if (dynaBean.containsKey(thisFields[j])) {
                            bean.set(targerFields[j], dynaBean.get(thisFields[j]));
                            dynaBean.set(targerFields[j], dynaBean.get(thisFields[j]));
                        }
                    }
                }
                if (StringUtil.isNotEmpty(pkValue)) {
                    bean.set(pkCode, pkValue);
                    dynaBean.set(pkCode, pkValue);
                    metaService.update(bean);
                } else if ("1".equalsIgnoreCase(insertFlag)) {
                    buildModelCreateInfo(bean);
                    metaService.insert(bean);
                    dynaBean.set(viewPkCode, bean.getStr(pkCode));
                }
            }
        }
    }


    @Override
    public void doChildrenTree(DynaBean dynaBean, String funcCode) {
        if (StringUtil.isEmpty(funcCode)) {
            return;
        }
        FuncInfo funcInfo = funInfoManager.getFuncInfo(funcCode);
        String mainPkCode = dynaBean.getPkCode();
        HashSet<Object> tableCodes = new HashSet<>();
        //子功能集合
        List<FuncRelation> childrenList = funcInfo.getChildren();
        for (int i = 0; i < childrenList.size(); i++) {
            FuncRelation children = childrenList.get(i);
            //子功能类型
            String funcType = children.getType();
            //表名
            String tableName = children.getTableCode();
            //满足 (树形子功能 || 自定义表名的甘特图子功能) 则按照多根树操作
            if ("tree".equalsIgnoreCase(funcType)
                    || ("gantt".equalsIgnoreCase(funcType) && StringUtils.isNotBlank(tableName) && !"JE_GANTT_TASK".equals(tableName))) {

                if (StringUtils.isBlank(tableName)) {
                    throw new PlatformException("子功能 [" + children.getName() + "] 未配置表名", PlatformExceptionEnum.UNKOWN_ERROR);
                }
                //如果已经增加过则不处理
                if (tableCodes.contains(tableName)) {
                    continue;
                }

                String childPkCode = "";
                //取出外键的名称
                List<FuncRelationField> relatedFields = children.getChildFields();
                for (int j = 0; j < relatedFields.size(); j++) {
                    FuncRelationField childField = relatedFields.get(j);
                    if (childField.getFieldCode().equals(mainPkCode)) {
                        childPkCode = childField.getChildFieldCode();
                        break;
                    }
                }
                if (StringUtils.isBlank(childPkCode)) {
                    throw new PlatformException("子功能 [" + children.getName() + "] 缺少主功能主键字段配置", PlatformExceptionEnum.UNKOWN_ERROR);
                }
                String childUuid = JEUUID.uuid();
                DynaBean bean = new DynaBean(tableName, true);
                //赋值外键
                bean.set(childPkCode, dynaBean.getStr(mainPkCode));
                bean.set("SY_NODETYPE", NodeType.ROOT);
                bean.set("SY_LAYER", 0);
                bean.set("SY_PARENT", null);
                bean.set("SY_PATH", "/" + childUuid);
                bean.set("SY_ORDERINDEX", 1);
                bean.set("SY_TREEORDERINDEX", StringUtil.preFillUp("1", 6, '0'));
                bean.set(bean.getPkCode(), childUuid);
                buildModelCreateInfo(bean);
                metaService.insert(tableName, bean);
                tableCodes.add(tableName);
            }
        }
    }

    @Override
    public DynaBean doCopy(DynaBean dynaBean, String funcCode, String codeGenFieldInfo, String uploadableFields) {
        FuncInfo funcInfo = funInfoManager.getFuncInfo(funcCode);
        String tableCode = dynaBean.getTableCode();
        String pkCode = dynaBean.getPkCode();
        String oldPkValue = dynaBean.getPkValue();
        //老数据
        DynaBean oldBean = metaService.selectOneByPk(tableCode, oldPkValue);
        //新数据
        DynaBean newBean = oldBean.clone();
        //删除主键
        newBean.remove(pkCode);
        //处理编号
        if (StringUtil.isNotEmpty(codeGenFieldInfo)) {
            if (WebUtils.isSaas()) {
                EndUser currentUser = SecurityUserHolder.getCurrentUser();
                buildCode(codeGenFieldInfo, newBean, currentUser.getZhId());
            } else {
                buildCode(codeGenFieldInfo, newBean);
            }
        }
        //插入复制的数据生成主键
        buildModelCreateInfo(newBean);
        metaService.insert(newBean);
        //获取新主键
        String newPkValue = newBean.getPkValue();
        //如果是树形功能，修改树形字段
        if ("tree".equalsIgnoreCase(funcInfo.getFuncType())) {
            newBean.set("SY_PATH", oldBean.getStr("SY_PATH", "").replace(oldPkValue, newPkValue));
            metaService.update(newBean);
        }
        //复制附件
        if (StringUtil.isNotEmpty(uploadableFields)) {
            for (String fieldCode : uploadableFields.split(",")) {
                String userId = SecurityUserHolder.getCurrentUser().getUserId();
                List<FileCopyDTO> dtos = documentBusService.copyFiles(userId, tableCode, oldPkValue, fieldCode, newPkValue);
                if (!dtos.isEmpty()) {
                    FileCopyDTO dto = dtos.get(0);
                    oldBean.set(fieldCode, dto.getName() + "*" + dto.getFileKey());
                }
            }
        }

        copyChild(funcInfo, newBean, oldPkValue);
        return newBean;
    }

    private void copyChild(FuncInfo funcInfo, DynaBean dynaBean, String oldPkValue) {
        String pkName = dynaBean.getStr(BeanUtils.KEY_PK_CODE);
        List<FuncRelation> childrens = funcInfo.getChildren();
        for (FuncRelation children : childrens) {
            //不勾选级联复制 或者 类型为自定义 --> 则不复制
            if (!children.getCopyChild() || !ArrayUtils.contains(new String[]{"func", "tree", "childfuncfield"}, children.getType())) {
                continue;
            }
            List<FuncRelationField> relatedFields = children.getChildFields();
            String childTableCode = children.getTableCode();
            String foreignKey = BeanUtils.getInstance().getForeignKeyField(childTableCode, dynaBean.getTableCode(), pkName, relatedFields);
            //如果未找到外键不复制
            if (StringUtil.isEmpty(foreignKey)) {
                continue;
            }
            String funcCode = children.getCode();
            FuncInfo childFunInfo = funInfoManager.getFuncInfo(funcCode);
            if (childFunInfo != null) {
                List<FuncRelation> childChildrens = childFunInfo.getChildren();
                DynaBean childTable = BeanUtils.getInstance().getResourceTable(childTableCode);
                String childPkCode = BeanUtils.getInstance().getPKeyFieldNames(childTable);
                //如果子功能还含有子功能，则一条一条复制数据
                if ((childChildrens != null && childChildrens.size() > 0) || "tree".equals(children.getType())) {
                    //树形表的复制
                    List<DynaBean> childDatas = metaService.select(childTableCode, ConditionsWrapper.builder().eq(foreignKey, oldPkValue).apply(childFunInfo.getWhereSql()));
                    Map<String, String> pkMap = new HashMap<String, String>();
                    for (DynaBean childData : childDatas) {
                        String oldChildPkValue = childData.getStr(childPkCode);
                        childData.set(BeanUtils.KEY_TABLE_CODE, childTableCode);
                        childData.set(childPkCode, null);//主键设空
                        childData.set(foreignKey, dynaBean.getStr(pkName));//设置新的外键
                        buildModelCreateInfo(childData);
                        metaService.insert(childData);
                        pkMap.put(oldChildPkValue, childData.getStr(childPkCode));
                        childData.set(BeanUtils.KEY_TABLE_CODE, childTableCode);
                        if (childChildrens != null && childChildrens.size() > 0) {
                            copyChild(childFunInfo, childData, oldChildPkValue);
                        }
                    }
                    //如果是树形功能则替换父节点及路径 父节点路径
                    if ("tree".equals(children.getType())) {
                        for (Map.Entry<String, String> entry : pkMap.entrySet()) {
                            metaService.executeSql(ConditionsWrapper.builder(
                                    "UPDATE " + childTableCode +
                                            " SET SY_PARENT=REPLACE(SY_PARENT,'" + entry.getKey() + "','" + entry.getValue() + "')," +
                                            " SY_PARENTPATH=REPLACE(SY_PARENTPATH,'" + entry.getKey() + "','" + entry.getValue() + "')," +
                                            " SY_PATH=REPLACE(SY_PATH,'" + entry.getKey() + "','" + entry.getValue() + "') WHERE " + foreignKey + "=" + "'" + dynaBean.getStr(pkName) + "'")
                                    .table(childTableCode));
                        }
                    }
                } else {
                    EndUser currentUser = SecurityUserHolder.getCurrentUser();
                    Department currentDept = SecurityUserHolder.getCurrentUserDept();
                    String createTime = DateUtils.formatDateTime(new Date());
                    String queryColumns = BeanUtils.getInstance().getFieldNames(childTable, new String[]{childPkCode, foreignKey, "SY_CREATETIME", "SY_CREATEORG", "SY_CREATEORGNAME", "SY_CREATEUSER", "SY_CREATEUSERNAME", "SY_AUDFLAG", "SY_PDID", "SY_PIID"});
                    StringBuffer insertSql = new StringBuffer();
                    String uuidStr = DBSqlUtils.getPcDBMethodManager().getGenerateUUID();
                    insertSql.append(" INSERT INTO  " + childTableCode + " (" + childPkCode + "," + foreignKey + "," + queryColumns + ",SY_CREATETIME,SY_CREATEORG,SY_CREATEORGNAME,SY_CREATEUSER,SY_CREATEUSERNAME,SY_AUDFLAG,SY_PDID,SY_PIID) ");
                    insertSql.append("SELECT " + uuidStr + ",'" + dynaBean.getStr(pkName) + "'," + queryColumns + ",'" + createTime + "','" + currentDept.getDeptCode() + "','" + currentDept.getDeptName() + "','" + currentUser.getUserCode() + "','" + currentUser.getUsername() + "','" + AudFlagStatus.NOSTATUS + "','','' FROM " + childTableCode + " WHERE " + foreignKey + "='" + oldPkValue + "' " + childFunInfo.getWhereSql());
                    metaService.executeSql(ConditionsWrapper.builder(insertSql.toString()).table(childTableCode));
                }
                //找到信息功能执行递归操作
            }
        }
    }

    @Override
    public void removeChild(String funcCode, String tableCode, String pkCode, String ids, boolean doTree) {

        //级联删除子功能
        if (StringUtil.isNotEmpty(funcCode)) {
            FuncInfo funcInfo = funInfoManager.getFuncInfo(funcCode);
            if (decideDeleteChildren(funcInfo)) {
                //封装条件
                ConditionsWrapper wrapper = ConditionsWrapper.builder();
                int i = 0;
                if (doTree) {
                    for (String id : ids.split(",")) {
                        if (i == 0) {
                            wrapper.like("SY_PATH", id);
                        } else {
                            wrapper.or().like("SY_PATH", id);
                        }
                        i++;
                    }
                }
                wrapper.in(pkCode, ids.split(","));
                List<DynaBean> lists = metaService.select(tableCode, wrapper);
                for (DynaBean bean : lists) {
                    removeChildData(bean, funcInfo);
                }
            }
        }
    }

    /**
     * 判断是否有子功能需级联删除
     *
     * @param funcInfo 功能对象
     * @return java.lang.Boolean
     */
    public Boolean decideDeleteChildren(FuncInfo funcInfo) {
        String tableCode = funcInfo.getTableCode();
        String pkName = funcInfo.getPkCode();
        List<FuncRelation> childrens = funcInfo.getChildren();
        for (FuncRelation children : childrens) {
            if (ArrayUtils.contains(new String[]{"func", "tree", "childfuncfield"}, children.getType())) {
                String childTableCode = children.getTableCode();
                List<FuncRelationField> relatedFields = children.getChildFields();
                List<FuncRelationField> delRelatedFields = new ArrayList<>();
                //遍历主子关联字段
                for (FuncRelationField childField : relatedFields) {
                    //找到需要级联删除的字段
                    if (childField.getDeleteChild()) {
                        delRelatedFields.add(childField);
                    }
                }
                if (delRelatedFields.size() == 0) {
                    continue;
                }
                return true;
            }
        }
        return false;
    }

    public void removeChildData(DynaBean dynaBean, FuncInfo funcInfo) {
        String pkName = dynaBean.getStr(BeanUtils.KEY_PK_CODE);
        String tableCode = dynaBean.getStr(BeanUtils.KEY_TABLE_CODE);
        List<FuncRelation> childrens = funcInfo.getChildren();
        for (FuncRelation children : childrens) {
            if (!ArrayUtils.contains(new String[]{"func", "tree", "childfuncfield"}, children.getType())) {
                continue;
            }
            String childTableCode = children.getTableCode();
            List<FuncRelationField> relatedFields = children.getChildFields();
            List<FuncRelationField> delRelatedFields = new ArrayList<>();
            //遍历主子关联字段
            for (FuncRelationField childField : relatedFields) {
                //找到需要级联删除的字段
                if (childField.getDeleteChild()) {
                    delRelatedFields.add(childField);
                }
            }
            if (delRelatedFields.size() == 0) {
                continue;
            }
            //构建主子SQL 并查询出子数据
            String childSql = funInfoManager.buildWhereSql4funcRelation(delRelatedFields, dynaBean);
            List<DynaBean> lists = metaService.select(childTableCode, ConditionsWrapper.builder().apply(QueryBuilder.trimSql(childSql)));
            if (lists.size() == 0) {
                continue;
            }

            String funcCode = children.getCode();
            FuncInfo childFunInfo = funInfoManager.getFuncInfo(funcCode);
            if (childFunInfo != null) {
                String childPkCode = childFunInfo.getPkCode();
                for (DynaBean childBean : lists) {
                    removeChildData(childBean, childFunInfo);
                }
                metaService.executeSql(ConditionsWrapper.builder(" DELETE FROM " + childTableCode +
                        " WHERE " + childPkCode + " IN (" + StringUtil.buildArrayToString(ArrayUtils.getBeanFieldArray(lists, childPkCode)) + ")")
                        .table(childTableCode)
                );
            }
        }
    }

    /**
     * 删除批量附件处理
     *
     * @param tableCode 表code
     * @param ids
     */
    @Override
    public void doRemoveBatchFiles(String tableCode, String ids) {
        //获取用户id
        String userId = SecurityUserHolder.getCurrentUser().getUserId();

        taskExecutor.execute(() -> {
            //删除文件
            documentBusService.deleteFiles(tableCode, ids, userId);
        });
    }

    /**
     * 删除树形批量附件处理
     *
     * @param tableCode 表code
     * @param ids
     */
    @Override
    public void doRemoveTreeBatchFiles(String tableCode, String ids) {
        //业务主键集合
        List<String> pkValues = new ArrayList<>();
        for (String id : ids.split(",")) {
            //获取主键字段名
            String pkCode = BeanUtils.getInstance().getPKeyFieldNames(tableCode);
            //查询业务数据主键集合
            List<DynaBean> busBeans = metaService.select(tableCode, ConditionsWrapper.builder().like("SY_PATH", id));
            for (DynaBean bean : busBeans) {
                pkValues.add(bean.getStr(pkCode));
            }
        }
        String userId = SecurityUserHolder.getCurrentUser().getUserId();

        taskExecutor.execute(() -> {
            //删除文件
            documentBusService.deleteFiles(tableCode, ArrayUtils.join(pkValues), userId);
        });
    }


    @Override
    public int doViewDelData(String viewConfigInfo, String viewTableCode, String mainPkCode, String ids) {
        JSONArray arrays = JSONArray.parseArray(viewConfigInfo);
        List<DynaBean> lists = metaService.select(viewTableCode, ConditionsWrapper.builder().in(mainPkCode, ids.split(",")));
        for (int i = 0; i < arrays.size(); i++) {
            JSONObject obj = arrays.getJSONObject(i);
            String tableCode = obj.getString("tableCode");
            String pkCode = obj.getString("pkCode");
            String viewPkCode = obj.getString("viewFieldCode");
            String fieldCodes = obj.getString("fieldCodes");
            String deleteFlag = "0";
            String doFieldCodes = "";
            if (obj.containsKey("doFieldCodes")) {
                doFieldCodes = obj.getString("doFieldCodes");
            }
            if (obj.containsKey("deleteData")) {
                deleteFlag = obj.getString("deleteData");
            }
            if (StringUtil.isNotEmpty(tableCode) && StringUtil.isNotEmpty(pkCode) && StringUtil.isNotEmpty(viewPkCode) && "1".equals(deleteFlag)) {
                return metaService.delete(tableCode, ConditionsWrapper.builder().in(pkCode, ArrayUtils.getBeanFieldArray(lists, viewPkCode)));
            }
        }
        return 0;
    }

    @Override
    public void doRemoveData(String tableCode, String pkCode, String ids, boolean mark, boolean funcEdit, boolean postil, boolean doTree) {
        if (StringUtil.isEmpty(ids)) {
            return;
        }
        if (doTree) {
            if (funcEdit) {
                for (String id : ids.split(",")) {
                    metaService.executeSql(" DELETE FROM JE_CORE_FUNCEDIT WHERE FUNCEDIT_TABLECODE='" + tableCode + "' AND FUNCEDIT_PKVALUE IN (SELECT " + pkCode + " FROM " + tableCode + " WHERE SY_PATH LIKE '%" + id + "%')");
                }
            }
            if (mark) {
                for (String id : ids.split(",")) {
                    metaService.executeSql(" DELETE FROM JE_CORE_MARK WHERE MARK_TABLECODE='" + tableCode + "' AND MARK_MODELID IN (SELECT " + pkCode + " FROM " + tableCode + " WHERE SY_PATH LIKE '%" + id + "%')");
                }
            }
            if (postil) {
                for (String id : ids.split(",")) {
                    metaService.executeSql(" DELETE FROM JE_CORE_POSTIL WHERE POSTIL_TABLECODE='" + tableCode + "' AND POSTIL_MODELID IN (SELECT " + pkCode + " FROM " + tableCode + " WHERE SY_PATH LIKE '%" + id + "%')");
                }
            }
        } else {
            if (funcEdit) {
                metaService.executeSql(" DELETE FROM JE_CORE_FUNCEDIT WHERE FUNCEDIT_TABLECODE='" + tableCode + "' AND FUNCEDIT_PKVALUE IN (" + StringUtil.buildArrayToString(ids.split(",")) + ")");
            }
            if (mark) {
                metaService.executeSql(" DELETE FROM JE_CORE_MARK WHERE MARK_TABLECODE='" + tableCode + "' AND MARK_MODELID IN (" + StringUtil.buildArrayToString(ids.split(",")) + ")");
            }
            if (postil) {
                metaService.executeSql(" DELETE FROM JE_CORE_POSTIL WHERE POSTIL_TABLECODE='" + tableCode + "' AND POSTIL_MODELID IN (" + StringUtil.buildArrayToString(ids.split(",")) + ")");
            }
        }
    }

    @Override
    public List<Map> doInsertUpdateList(String tableCode, String strData, String funcType, String codeGenFieldInfo, String viewConfigInfo) {
        List<Map> updateList = new ArrayList<>();
        List<DynaBean> lists = BeanUtils.getInstance().buildUpdateList(strData, tableCode);
        for (DynaBean bean : lists) {
            if ("view".equals(funcType) && StringUtil.isNotEmpty(viewConfigInfo)) {
                doViewData(viewConfigInfo, bean);
            }
            String pkValue = bean.getPkValue();
            //操作    如果不包含该参数，  则按原来处理，， 如果包含。。 是update  有主键才会去更新
            String action = bean.getStr("__action__");
            if (StringUtil.isNotEmpty(pkValue) && (!bean.containsKey("__action__") || "doUpdate".equals(action))) {
                buildModelModifyInfo(bean);
                metaService.update(bean);
                updateList.add(bean.getValues());
            } else {
                buildModelCreateInfo(bean);
                if (StringUtil.isNotEmpty(codeGenFieldInfo)) {
                    if (WebUtils.isSaas()) {
                        EndUser currentUser = SecurityUserHolder.getCurrentUser();
                        buildCode(codeGenFieldInfo, bean, currentUser.getZhId());
                    } else {
                        buildCode(codeGenFieldInfo, bean);
                    }
                }
                //默认为启用数据
                bean.set("SY_STATUS", "1");
                metaService.insert(bean);
                updateList.add(bean.getValues());
            }
        }
        return updateList;
    }

    @Override
    public List<DynaBean> doUpdateList(String tableCode, String updateStr, String funcType, String funcCode, String codeGenFieldInfo) {
        List<DynaBean> updateList = new ArrayList<>();
        List<DynaBean> lists = BeanUtils.getInstance().buildUpdateList(updateStr, tableCode);
        for (DynaBean bean : lists) {
            if ("view".equals(funcType) && StringUtil.isNotEmpty(funcCode)) {
                doViewData(funcCode, bean);
            }
            String pkValue = bean.getPkValue();
            if (StringUtil.isNotEmpty(pkValue)) {
                buildModelModifyInfo(bean);
                metaService.update(bean);
            } else {
                buildModelCreateInfo(bean);
                if (StringUtil.isNotEmpty(codeGenFieldInfo)) {
                    if (WebUtils.isSaas()) {
                        EndUser currentUser = SecurityUserHolder.getCurrentUser();
                        buildCode(codeGenFieldInfo, bean, currentUser.getZhId());
                    } else {
                        buildCode(codeGenFieldInfo, bean);
                    }
                }
                //默认为启用数据
                bean.set("SY_STATUS", "1");
                doSave(bean);
            }
            updateList.add(bean);
        }
        return updateList;
    }

    @Override
    public int doUpdateAllList(String tableCode, String funcType, String funcCode, Map<String, Object> values, MethodArgument param) {
        DynaBean funcInfo = metaService.selectOne("JE_CORE_FUNCINFO",
                ConditionsWrapper.builder().eq("FUNCINFO_FUNCCODE", funcCode), "FUNCINFO_VIEWCONFIGINFO,FUNCINFO_FUNCTYPE,FUNCINFO_TABLENAME,JE_CORE_FUNCINFO_ID");
        funcType = funcInfo.getStr("FUNCINFO_FUNCTYPE");
        String viewConfigInfo = funcInfo.getStr("FUNCINFO_VIEWCONFIGINFO");
        if (funcType.equals("view") && !(StringUtils.isBlank(viewConfigInfo) || viewConfigInfo.equals("[]"))) {
            //如果配置为空，只修改当前表数据
            String funcId = funcInfo.getStr("JE_CORE_FUNCINFO_ID");
            param.setTableCode(funcInfo.getStr("FUNCINFO_TABLENAME"));
            param.setFuncId(funcId);
            ConditionsWrapper conditionsWrapper = manager.buildWrapper(param);
            //构建查询条件
            List<DynaBean> lists = metaService.select(funcInfo.getStr("FUNCINFO_TABLENAME"), conditionsWrapper);
            for (DynaBean bean : lists) {
                Map<String, Object> updateValues = param.getDynaBean().getValues();
                for (Map.Entry<String, Object> entry : updateValues.entrySet()) {
                    bean.set(entry.getKey(), entry.getValue());
                }
                doViewData(funcCode, bean, viewConfigInfo);
            }
            return lists.size();
        } else {
            String funcId = funcInfo.getStr("JE_CORE_FUNCINFO_ID");
            param.setTableCode(funcInfo.getStr("FUNCINFO_TABLENAME"));
            param.setFuncId(funcId);
            ConditionsWrapper conditionsWrapper = manager.buildWrapper(param);
            DynaBean dynaBean =new DynaBean();
            dynaBean.table(tableCode);
            dynaBean.setValues(values);
            int i = metaService.update(dynaBean,conditionsWrapper);
            return i;
        }

    }

    @Override
    public List<DynaBean> doUpdateList(String tableCode, String updateStr, String funcType, String viewConfigInfo) {
        List<DynaBean> updateList = new ArrayList<>();
        List<DynaBean> lists = BeanUtils.getInstance().buildUpdateList(updateStr, tableCode);
        for (DynaBean bean : lists) {
            String pkValue = bean.getPkValue();
            if ("view".equals(funcType) && StringUtil.isNotEmpty(viewConfigInfo)) {
                doViewData(viewConfigInfo, bean);
            }
            if (StringUtil.isNotEmpty(pkValue)) {
                buildModelModifyInfo(bean);
                metaService.update(bean);
            } else {
                buildModelCreateInfo(bean);
                //默认为启用数据
                bean.set("SY_STATUS", "1");
                metaService.insert(bean);
            }
            updateList.add(bean);
        }
        return updateList;
    }

    @Override
    public DynaBean treeMove(DynaBean dynaBean) {
        String tableCode = dynaBean.getStr(BeanUtils.KEY_TABLE_CODE);
        String pkName = dynaBean.getStr(BeanUtils.KEY_PK_CODE);
        DynaBean bean = metaService.selectOneByPk(tableCode, dynaBean.getStr(pkName), pkName + ",SY_TREEORDERINDEX,SY_ORDERINDEX,SY_PATH,SY_PARENTPATH,SY_PARENTPATH,SY_LAYER,SY_PARENT");
        String newParentId = dynaBean.getStr("SY_PARENT");
        String oldParentId = bean.getStr("SY_PARENT");
        String oldPath = bean.getStr("SY_PATH");
        String oldParentPath = bean.getStr("SY_PARENTPATH");
        String oldTreeOrderIndex = bean.getStr("SY_TREEORDERINDEX");
        Integer chaLayer = dynaBean.getInt("SY_LAYER", 0) - bean.getInt("SY_LAYER", 0);
        bean.set("SY_PARENT", newParentId);
        bean.set(BeanUtils.KEY_TABLE_CODE, tableCode);
        DynaBean parent = metaService.selectOneByPk(tableCode, newParentId);
        bean.set("SY_PATH", parent.getStr("SY_PATH") + "/" + dynaBean.getStr(pkName));
        bean.set("SY_PARENTPATH", parent.getStr("SY_PATH"));
        bean.set("SY_PARENT", newParentId);
        bean.set("SY_LAYER", parent.getInt("SY_LAYER", 0) + 1);
        if (NodeType.LEAF.equals(parent.getStr("SY_NODETYPE"))) {
            updateTreePanent4NodeType(tableCode, newParentId);
        }
        bean.set("SY_TREEORDERINDEX", parent.getStr("SY_TREEORDERINDEX"));
        generateTreeOrderIndex(bean);
        String subStringFunction = DBSqlUtils.getPcDBMethodManager().getSubString();
        String lengthFunction = DBSqlUtils.getPcDBMethodManager().getLength();
        //更新当前节点下所有孩子的路径信息
        metaService.executeSql(ConditionsWrapper.builder(
                "UPDATE " + tableCode + " SET SY_PATH=REPLACE(SY_PATH,'" + oldPath + "','" + bean.getStr("SY_PATH") + "')," +
                        " SY_PARENTPATH=REPLACE(SY_PARENTPATH,'" + oldParentPath + "','" + bean.getStr("SY_PARENTPATH") + "')," +
                        " SY_LAYER=(SY_LAYER+" + chaLayer + ")," +
                        " SY_TREEORDERINDEX=('" + bean.getStr("SY_TREEORDERINDEX") + "'+" + subStringFunction + "(SY_TREEORDERINDEX," + (oldTreeOrderIndex.length() + 1) + "," +
                        lengthFunction + "(SY_TREEORDERINDEX)-" + oldTreeOrderIndex.length() + "))" +
                        " WHERE SY_PATH LIKE '%" + oldPath + "%' AND " + pkName + "!='" + dynaBean.getStr(pkName) + "' AND " + lengthFunction + "(SY_TREEORDERINDEX)>" + oldTreeOrderIndex.length())
                .table(tableCode)
        );
        metaService.update(bean);
        updateTreePanent4NodeType(tableCode, oldParentId);
        return bean;
    }

    @Override
    public void updateTreePanent4NodeType(String tableCode, String parentId) {
        String pkName = BeanUtils.getInstance().getPKeyFieldNames(tableCode);
        long count = metaService.countBySql("select count(*) from " + tableCode + " where SY_PARENT={0}", parentId);
        DynaBean one = metaService.selectOneByPk(tableCode, parentId, pkName + ",SY_NODETYPE");
        if (count > 0) {
            if (NodeType.LEAF.equals(one.getStr("SY_NODETYPE"))) {
                one.set(BeanUtils.KEY_TABLE_CODE, tableCode);
                one.set("SY_NODETYPE", NodeType.GENERAL);
                metaService.update(one);
            }
        } else {
            if (NodeType.GENERAL.equals(one.getStr("SY_NODETYPE"))) {
                one.set(BeanUtils.KEY_TABLE_CODE, tableCode);
                one.set("SY_NODETYPE", NodeType.LEAF);
                if ("0".equals(one.getStr("SY_DISABLED", "0"))) {
                    metaService.update(one);
                }
            }
        }
    }

    @Override
    public Boolean checkFieldUnique(DynaBean dynaBean, String fieldCode, Query query) {
        String tableCode = dynaBean.getTableCode();
        if (StringUtil.isEmpty(tableCode) || StringUtil.isEmpty(fieldCode)) {
            return false;
        }
        //添加字段唯一性校验条件
        query.addCustom(fieldCode, ConditionEnum.EQ, dynaBean.getStr(fieldCode));
        //构建where条件
        ConditionsWrapper queryWrapper = query.buildWrapper();

        //构建count语句  并加入where条件
        ConditionsWrapper countWrapper = ConditionsWrapper.builder()
                .putAll(queryWrapper.getParameter())
                .apply(String.format("select count(1) from %s where ", QueryBuilder.trimBlank(tableCode)))
                .apply(queryWrapper.getSql());
        Long count = metaService.countBySql(countWrapper);
        return count <= 0;
    }

    @Override
    public void doDataFuncEdit(String funcCode, String tableCode, String pkValue, String userId, String isNew) {
        DynaBean funcEdit = metaService.selectOne("JE_CORE_FUNCEDIT", ConditionsWrapper.builder()
                .eq("FUNCEDIT_FUNCCODE", funcCode).eq("FUNCEDIT_PKVALUE", pkValue).eq("FUNCEDIT_USERID", userId));
        boolean insertFlag = false;
        if (funcEdit == null) {
            funcEdit = new DynaBean("JE_CORE_FUNCEDIT", true);
            insertFlag = true;
        }
        funcEdit.set("FUNCEDIT_FUNCCODE", funcCode);
        funcEdit.set("FUNCEDIT_TABLECODE", tableCode);
        funcEdit.set("FUNCEDIT_PKVALUE", pkValue);
        funcEdit.set("FUNCEDIT_USERID", userId);
        funcEdit.set("FUNCEDIT_NEW", isNew);
        if (insertFlag) {
            metaService.insert(funcEdit);
        } else {
            metaService.update(funcEdit);
        }
    }

    @Override
    public List<Map<String, Object>> loadGridTree(String rootId, String tableCode, String excludes, Boolean checked, Query query) {
        DynaBean table = BeanUtils.getInstance().getResourceTable(tableCode);
        JSONTreeNode template = BeanUtils.getInstance().buildJSONTreeNodeTemplate((List<DynaBean>) table.get(BeanUtils.KEY_TABLE_COLUMNS));
        List<Map<String, Object>> datas = loadTree(rootId, template, table, excludes, checked, query);
        Map<String, Object> root = buildJSONTree4Dyna(datas, table.getStr(BeanUtils.KEY_PK_CODE), template.getParent());
        List<Map<String, Object>> childrens = (List<Map<String, Object>>) root.get("children");
        return childrens;
    }

    /**
     * 查询属性表数据(无树形结构)
     *
     * @param rootId   根节点id
     * @param template 表字段与树形字段对应关系
     * @param table    表信息
     * @param excludes
     * @param checked
     * @param query    查询信息
     * @return java.util.List
     */
    public List<Map<String, Object>> loadTree(String rootId, JSONTreeNode template, DynaBean table, String excludes, Boolean checked, Query query) {

        //资源表信息
        String tableCode = table.getStr(BeanUtils.KEY_TABLE_CODE);
        List<DynaBean> columns = (List<DynaBean>) table.get(BeanUtils.KEY_TABLE_COLUMNS);

        //字段sql
        StringBuffer filedSql = new StringBuffer();
        for (DynaBean column : columns) {
            filedSql.append(" ").append(column.getStr("TABLECOLUMN_CODE")).append(",");
        }
        filedSql.deleteCharAt(filedSql.length() - 1);
        // 拼接语句
        ConditionsWrapper _select = ConditionsWrapper.builder().apply(" SELECT ").apply(filedSql.toString()).apply(" from ").apply(tableCode).apply(" WHERE ")
                //(SY_PATH LIKE '%ROOT%' + whereSql )
                .and(i -> {
                    i.like(template.getNodePath(), rootId);
                    query.buildWrapper(i);
                })
                // OR ID = 'ROOT'
                .or().eq(template.getId(), rootId);
        //order条件
        if (query != null && StringUtil.isNotEmpty(query.getFuncOrderSql())) {
            _select.apply(query.getFuncOrderSql());
        } else {
            _select.apply(" ORDER BY ").apply(template.getParent()).apply(" asc");
            if (StringUtil.isNotEmpty(template.getOrderIndex())) {
                _select.apply(", ").apply(template.getOrderIndex()).apply(" asc ");
            }
        }

        //查询数据
        List<Map<String, Object>> list = metaService.selectSql(_select.table(tableCode));
        list.forEach(item -> {
            //"id","text","cls","leaf","href","hrefTarget","expandable","description","code","icon","iconCls","bigIcon","bigIconCls","parent","nodeInfo","nodeInfoType","disabled","nodePath"
            item.put("children", new ArrayList<Map>());
            item.put("id", item.get(template.getId()));
            item.put("text", item.get(template.getText()));
            item.put("code", item.get(template.getCode()));
            item.put("parent", item.get(template.getParent()));
            if (StringUtil.isNotEmpty(template.getNodeInfo())) {
                item.put("nodeInfo", item.get(template.getNodeInfo()));
            }
            if (StringUtil.isNotEmpty(template.getNodeInfoType())) {
                item.put("nodeInfoType", item.get(template.getNodeInfoType()));
            }
            if (StringUtil.isNotEmpty(template.getNodeType())) {
                item.put("nodeType", item.get(template.getNodeType()));
            }
            if (StringUtil.isNotEmpty(template.getIcon())) {
                item.put("icon", item.get(template.getIcon()));
            }
            if (StringUtil.isNotEmpty(template.getIconCls())) {
                item.put("iconCls", item.get(template.getIconCls()));
            }
            if (StringUtil.isNotEmpty(template.getLayer())) {
                item.put("layer", item.get(template.getLayer()));
            }
            if (StringUtil.isNotEmpty(template.getDisabled())) {
                item.put("disabled", item.get(template.getDisabled()));
            }
            if (StringUtil.isNotEmpty(template.getNodePath())) {
                item.put("nodePath", item.get(template.getNodePath()));
            }
            if (StringUtil.isNotEmpty(template.getParentPath())) {
                item.put("parentPath", item.get(template.getParentPath()));
            }
            if (StringUtil.isNotEmpty(template.getHref())) {
                item.put("href", item.get(template.getHref()));
            }
            if (StringUtil.isNotEmpty(template.getHrefTarget())) {
                item.put("hrefTarget", item.get(template.getHrefTarget()));
            }
            if (StringUtil.isNotEmpty(template.getDescription())) {
                item.put("description", item.get(template.getDescription()));
            }
            if (StringUtil.isNotEmpty(template.getOrderIndex())) {
                item.put("orderIndex", item.get(template.getOrderIndex()));
            }
            item.put("checked", checked);
            item.put("leaf", true);
            item.put("children", new ArrayList<HashMap>());
            for (String exclude : excludes.split(",")) {
                item.remove(exclude);
            }
            // TODO 如果是oracle则特殊处理
            if (PCDaoTemplateImpl.DBNAME.equals(ConstantVars.STR_ORACLE)) {
                for (Object key : item.keySet()) {
                    if (item.get(key + "") != null && item.get(key + "") instanceof Clob) {
                        item.put(key + "", StringUtil.getClobValue(item.get(key + "")));
                    }
                }
            }
        });
        return list;
    }

    /**
     * list转树形
     *
     * @param lists
     * @param pkCode
     * @param parentCode
     * @return java.util.Map
     */
    public Map<String, Object> buildJSONTree4Dyna(List<Map<String, Object>> lists, String pkCode, String parentCode) {
        Map<String, Object> root = new HashMap<>();
        //当前循环这个集合每一个元素
        for (Map<String, Object> node : lists) {
            if (node.get(parentCode) == null || node.get(parentCode).equals("")) {
                root = node;
                lists.remove(node);
                break;
            }
        }
        createTreeChildren(lists, root, pkCode, parentCode);
        return root;
    }

    /**
     * 递归构建树形数据
     *
     * @param childrens
     * @param root
     * @param pkCode
     * @param parentCode
     * @return void
     */
    private void createTreeChildren(List<Map<String, Object>> childrens, Map<String, Object> root, String pkCode, String parentCode) {
        String parentId = (String) root.get(pkCode);
        for (int i = 0; i < childrens.size(); i++) {
            Map<String, Object> node = childrens.get(i);
            if (node.get(parentCode) != null) {
                if (node.get(parentCode).toString().equalsIgnoreCase(parentId)) {
                    ((List<Map>) root.get("children")).add(node);
                    if (((List<Map>) root.get("children")).size() > 0) {
                        root.put("leaf", false);
                    }
                    //当前不能删除节点，因为孩子引用与它， 递归回来，坐标失效
                    createTreeChildren(childrens, node, pkCode, parentCode);
                }
                if (i == childrens.size() - 1) {
                    return;
                }
            }
        }
    }

    @Override
    public List<JSONTreeNode> loadTreeNodeList(String rootId, String tableName, JSONTreeNode template, Query where, List<String> includeIds, String[] beanFields) {
        List<JSONTreeNode> list = new ArrayList<>();
        if (TreeUtil.verify(template)) {

            //拼接sql
            StringBuilder filedSql = new StringBuilder();
            filedSql.append(" select ").append(template.getId()).append(",").append(template.getCode()).append(",").append(template.getText()).append(",").append(template.getParent());
            // 英文名称
            if (StringUtil.isNotEmpty(template.getEnField())) {
                filedSql.append(",").append(template.getEnField());
            }
            if (StringUtil.isNotEmpty(template.getParentText())) {
                filedSql.append(",").append(template.getParentText());
            }
            // 节点类型
            if (StringUtil.isNotEmpty(template.getNodeType())) {
                filedSql.append(",").append(template.getNodeType());
            }
            // 节点信息
            if (StringUtil.isNotEmpty(template.getNodeInfo())) {
                filedSql.append(",").append(template.getNodeInfo());
            }
            // 节点信息类型
            if (StringUtil.isNotEmpty(template.getNodeInfoType())) {
                filedSql.append(",").append(template.getNodeInfoType());
            }
            if (StringUtil.isNotEmpty(template.getLayer())) {
                filedSql.append(",").append(template.getLayer());
            }
            // 图标图片地址
            if (StringUtil.isNotEmpty(template.getIcon())) {
                filedSql.append(",").append(template.getIcon());
            }
            // 图标样式
            if (StringUtil.isNotEmpty(template.getIconCls())) {
                filedSql.append(",").append(template.getIconCls());
            }
            //是否禁用
            if (StringUtil.isNotEmpty(template.getDisabled())) {
                filedSql.append(",").append(template.getDisabled());
            }
            //树形路径
            if (StringUtil.isNotEmpty(template.getNodePath())) {
                filedSql.append(",").append(template.getNodePath());
            }
            //树形父节点路径
            if (StringUtil.isNotEmpty(template.getParentPath())) {
                filedSql.append(",").append(template.getParentPath());
            }
            //链接
            if (StringUtil.isNotEmpty(template.getHref())) {
                filedSql.append(",").append(template.getHref());
            }
            //链接目标
            if (StringUtil.isNotEmpty(template.getHrefTarget())) {
                filedSql.append(",").append(template.getHrefTarget());
            }
            //描述
            if (StringUtil.isNotEmpty(template.getDescription())) {
                filedSql.append(",").append(template.getDescription());
            }
            if (StringUtil.isNotEmpty(template.getOrderIndex())) {
                filedSql.append(",").append(template.getOrderIndex());
            }
            if (StringUtil.isNotEmpty(template.getTreeOrderIndex())) {
                filedSql.append(",").append(template.getTreeOrderIndex());
            }
            if (StringUtil.isNotEmpty(template.getImportType())) {
                filedSql.append(",").append(template.getImportType());
            }
            if (StringUtil.isNotEmpty(template.getFieldCodes())) {
                filedSql.append(template.getFieldCodes());
            }
            filedSql.append(" FROM ").append(tableName).append(" where ");

            //创建查询
            ConditionsWrapper select = ConditionsWrapper.builder().apply(filedSql.toString());
            // 拼接语句
            //(SY_PATH LIKE '%ROOT%' + whereSql )
            select.and(i -> {
                //加入传过来的where条件和预处理参数
                where.buildWrapper(i);
                i.like(template.getNodePath(), rootId);
            });
            // OR ID = 'ROOT'
            select.or().eq(template.getId(), rootId);
            //orderSql
            String orderSql = where.buildOrder();
            if (StringUtils.isBlank(orderSql)) {
                orderSql = " ORDER BY " + template.getParent() + " asc";
                if (StringUtil.isNotEmpty(template.getOrderIndex())) {
                    orderSql += ", " + template.getOrderIndex() + " asc";
                }
                select.apply(orderSql);
            } else {
                select.apply(" ORDER BY ").apply(orderSql);
            }

            //执行查询
            List<Map<String, Object>> treeItems = metaService.selectSql(select.table(tableName));

            //遍历结果构建树形节点对象
            treeItems.forEach(record -> {

                //主键
                String nodeId = (String) record.get(template.getId());
                //排除不在指定节点内的数据
                if (includeIds != null && includeIds.size() > 0 && !includeIds.contains(nodeId)) {
                    return;
                }
                JSONTreeNode node = new JSONTreeNode();
                node.setId(nodeId);
                node.setKey(nodeId);
                //名称
                node.setText((String) record.get(template.getText()));
                //编码
                node.setCode((String) record.get(template.getCode()));
                //父节点
                node.setParent((String) record.get(template.getParent()));
                //节点信息
                if (StringUtil.isNotEmpty(template.getNodeInfo())) {
                    node.setNodeInfo(StringUtil.getClobValue(record.get(template.getNodeInfo())));
                }
                //英文名称
                if (StringUtil.isNotEmpty(template.getEnField())) {
                    node.setEnField(record.get(template.getEnField()) + "");
                }
                //父节点名称
                if (StringUtil.isNotEmpty(template.getParentText())) {
                    node.setParentText(record.get(template.getParentText()) + "");
                }
                //节点信息类型
                if (StringUtil.isNotEmpty(template.getNodeInfoType())) {
                    node.setNodeInfoType(record.get(template.getNodeInfoType()) + "");
                }
                //是否叶子
                if (StringUtil.isNotEmpty(template.getNodeType())) {
                    node.setLeaf(NodeType.LEAF.equalsIgnoreCase(record.get(template.getNodeType()) + ""));
                    node.setNodeType(record.get(template.getNodeType()) + "");
                }
                if (StringUtil.isNotEmpty(template.getLayer())) {
                    node.setLayer(record.get(template.getLayer()) + "");
                }
                //图标图片地址
                if (StringUtil.isNotEmpty(template.getIcon())) {
                    node.setIcon(record.get(template.getIcon()) + "");
                }
                //图标样式
                if (StringUtil.isNotEmpty(template.getIconCls())) {
                    node.setIconCls(record.get(template.getIconCls()) + "");
                }
                //是否禁用
                if (StringUtil.isNotEmpty(template.getDisabled())) {
                    node.setDisabled(record.get(template.getDisabled()) + "");
                } else {
                    node.setDisabled("0");
                }
                //树形路径
                if (StringUtil.isNotEmpty(template.getNodePath())) {
                    node.setNodePath(record.get(template.getNodePath()) + "");
                }
                //树形父节点路径
                if (StringUtil.isNotEmpty(template.getParentPath())) {
                    node.setParentPath(record.get(template.getParentPath()) + "");
                }
                //链接
                if (StringUtil.isNotEmpty(template.getHref())) {
                    node.setHref(record.get(template.getHref()) + "");
                }
                //链接目标
                if (StringUtil.isNotEmpty(template.getHrefTarget())) {
                    node.setHrefTarget(record.get(template.getHrefTarget()) + "");
                }
                //描述
                if (StringUtil.isNotEmpty(template.getDescription())) {
                    node.setDescription(StringUtil.getClobValue(record.get(template.getDescription())));
                }
                //排序
                if (StringUtil.isNotEmpty(template.getOrderIndex())) {
                    node.setOrderIndex(record.get(template.getOrderIndex()) + "");
                }
                if (StringUtil.isNotEmpty(template.getTreeOrderIndex())) {
                    node.setTreeOrderIndex(record.get(template.getTreeOrderIndex()) + "");
                }
                if (StringUtil.isNotEmpty(template.getImportType())) {
                    String importType = record.get(template.getImportType())==null?"0":record.get(template.getImportType()).toString();
                    record.put(template.getImportType(),importType);
                    node.setImportType(record.get(template.getImportType()) + "");
                }

                //保留指定字段
                if (beanFields != null && beanFields.length > 0) {
                    List<String> fieldList = Arrays.asList(beanFields);
                    Set<String> keySet = record.keySet();
                    for (String key : keySet) {
                        if (!fieldList.contains(key)) {
                            record.remove(key);
                        }
                        ;
                    }

                }
                //如果是oracle则单独处理
                if (PCDaoTemplateImpl.DBNAME.equals(ConstantVars.STR_ORACLE)) {
                    record.forEach((key, val) -> {
                        if (val == null) {
                            record.put(key, "");
                        } else if (val instanceof Clob) {
                            record.put(key, StringUtil.getClobValue(record.get(key)));
                        }
                    });
                }
                node.setBean(record);
                list.add(node);
            });
        }
        return list;
    }

    @Override
    public JSONTreeNode buildJSONNewTree(List<JSONTreeNode> lists, String rootId) {
        JSONTreeNode root = new JSONTreeNode();
        for (JSONTreeNode node : lists) { //当前循环这个集合每一个元素
            if (node.getParent() == null || node.getParent().equals("") || node.getId().equals(rootId)) {
                root = node;
                lists.remove(node);
                break;
            }
        }
        createTreeChildren(lists, root);
        return root;
    }

    public void createTreeChildren(List<JSONTreeNode> childrens, JSONTreeNode root) {
        String parentId = root.getId();
        for (int i = 0; i < childrens.size(); i++) {
            JSONTreeNode node = childrens.get(i);
//			if(node.getParent()!=null){
            if (parentId.equals(node.getParent())) {
                node.setParentText(root.getText());
                node.setTitle(root.getText());
                root.getChildren().add(node);
                //当前不能删除节点，因为孩子引用与它， 递归回来，坐标失效
//                if (node.isLeaf() == false) {
                createTreeChildren(childrens, node);
//                }
            }
//			}
            if (i == childrens.size() - 1) {
//				if(root.getChildren().size()==0){
//					root.setLeaf(true);
//				}else{
//					root.setLeaf(false);
//				}
                if (root.getChildren().size() > 0) {
                    root.setLeaf(false);
                }
                return;
            }
        }
    }

    @Override
    public FuncInfo functionConfig(String funcCode) {
        return funInfoManager.getFuncInfo(funcCode);
    }

    @Override
    public FuncPermVo functionPerm(String funcCode) {
        return funcPermManager.getFuncPerm(funcCode);
    }

}
